package views;

import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;

import auxiliary.InputGenerator;
import structure.Frame;

import common.IActionHandler;
import common.INTERIOR_BOT;
import common.Message;

public class MainView implements Observer {

	Display display;
	Shell shell;
	Label titleLabel;
	Button loadButton;
	Canvas canvas1;
	Canvas canvas2;
	StyledText filePreviewStyledText;
	StyledText logStyledText;
	StyledText Heights; 
	StyledText Heights2;
	
	int canvas1Width = 645;
	int canvas1Height = 300;
	
	int canvas2Width = 645;
	int canvas2Height = 300;

	ArrayList<Frame> frames;
	PaintListener canvas1PaintListener;
	PaintListener canvas2PaintListener;
	
	public void buildGui(){
		display = Display.getDefault();
		shell = new Shell(display);
		shell.setSize(1330, 700);
		GridLayout shellGridLayout = new GridLayout();
		shellGridLayout.numColumns = 2;
		shell.setLayout(shellGridLayout);
		shell.setMaximized(true);
		
		titleLabel = new Label(shell, SWT.NONE);
		titleLabel.setText("\"3D-interior-bot\" Click load button > ");
		
		loadButton = new Button(shell, SWT.PUSH);
		loadButton.setText("Load Input");
		
		canvas1 = new Canvas(shell, SWT.BORDER);
		canvas2 = new Canvas(shell, SWT.BORDER);
		
		GridData canvas1GridData = new GridData();
		GridData canvas2GridData = new GridData();
		
		canvas1GridData.widthHint = canvas1Width;
		canvas1GridData.heightHint = canvas1Height;
		
		canvas2GridData.widthHint = canvas2Width;
		canvas2GridData.heightHint = canvas2Height;
		
		canvas1.setLayoutData(canvas1GridData);
		canvas1.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
		
		canvas2.setLayoutData(canvas2GridData);
		canvas2.setBackground(display.getSystemColor(SWT.COLOR_BLACK));
		
		filePreviewStyledText = new StyledText(shell, SWT.BORDER | SWT.V_SCROLL);
		filePreviewStyledText.setEditable(false);
		GridData filePreviewStyledTextGridData = new GridData();
		filePreviewStyledTextGridData.grabExcessHorizontalSpace = true;
		filePreviewStyledTextGridData.grabExcessVerticalSpace = true;
		filePreviewStyledTextGridData.widthHint = 650;
		filePreviewStyledTextGridData.heightHint = 300;
		filePreviewStyledText.setLayoutData(filePreviewStyledTextGridData);
		
		Heights = new StyledText(shell, SWT.BORDER | SWT.V_SCROLL);
		Heights.setEditable(false);
		GridData HeightsGridData = new GridData();
		HeightsGridData.grabExcessHorizontalSpace = true;
		HeightsGridData.grabExcessVerticalSpace = true;
		HeightsGridData.widthHint = 650;
		HeightsGridData.heightHint = 300;
		Heights.setLayoutData(HeightsGridData);
		
		logStyledText = new StyledText(shell, SWT.BORDER | SWT.V_SCROLL);
		logStyledText.setEditable(false);
		GridData logStyledTextGridData = new GridData();
		logStyledTextGridData.grabExcessHorizontalSpace = true;
		logStyledTextGridData.grabExcessVerticalSpace = true;
		logStyledTextGridData.widthHint = 650;
		logStyledTextGridData.heightHint = 300;
		logStyledText.setLayoutData(logStyledTextGridData);
		
		/* Heights2 = new StyledText(shell, SWT.BORDER | SWT.V_SCROLL);
		Heights2.setEditable(false);
		GridData Heights2GridData = new GridData();
		Heights2GridData.grabExcessHorizontalSpace = true;
		Heights2GridData.grabExcessVerticalSpace = true;
		Heights2GridData.widthHint = 650;
		Heights2GridData.heightHint = 300;
		Heights2.setLayoutData(Heights2GridData); */
		
		canvas1PaintListener = new PaintListener() {
			@Override
			public void paintControl(PaintEvent e) {
				if(null != frames){
					
			        for (int jj = 0; jj < frames.size() ; jj++ )
	     	        Heights.append( (638-(InputGenerator.nframes*jj)) + "," + frames.get(jj).getHeight() + "\n" );
					
					for(int i = 0; i < frames.size(); i++){
						int r = 255 - (i*10);
						int g = 255 - (i*10);
						int b = 255 - (i*10);
 						e.gc.setForeground(new Color(display, r, g, b));
 						int[] xys = transformCoordinatesPairs(frames.get(i).toArrayOfXyPoints());
 						for(int j = 0; j < xys.length; j+=2)
 							logStyledText.append(xys[j] + ", " + xys[j+1] + "\n");
 						e.gc.drawPolyline(xys);
 						e.gc.setForeground(new Color(display, r, g, b));
 						//e.gc.setBackground(new Color(display, r, g, b));
 						//e.gc.fillPolygon(xys);
 							
					}
					//logStyledText.update();
				}
			}
		};
		
		canvas1.addPaintListener(canvas1PaintListener);
		shell.open();
	}
	
	public void runGui(){
		while(!shell.isDisposed())
			if(!display.readAndDispatch())
				display.sleep();
		display.dispose();
	}
	
	public void registerAction(int action, final IActionHandler actionHandler){
		switch (action) {
			case INTERIOR_BOT.LOAD_FRAMES:
				loadButton.addSelectionListener(new SelectionAdapter() {
					public void widgetSelected(SelectionEvent e){
						actionHandler.handleAction();
					}
				});
			default:
				break;
		}
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public void update(Observable o, Object arg) {
		final Message msg = (Message) arg;
		switch (msg.header) {
			case INTERIOR_BOT.LOAD_FRAMES:
				String str = "";
				for(Frame f : (ArrayList<Frame>)msg.body)
					str += f.toString()+"\n";
				
				filePreviewStyledText.setText(str);
				frames = (ArrayList<Frame>)msg.body;
				canvas1.redraw();
			default:
				break;
		}
	}

	public int[] transformCoordinatesPair(int[] xy){
		return new int[]{xy[0]+canvas1Width/2, xy[1]+canvas1Height};
	}
	
	public int[] transformCoordinatesPair2(int[] xy){
		return new int[]{xy[0]+canvas2Width/2, xy[1]+canvas2Height};
	}
	
	public int[] transformCoordinatesPairs(int[] xys){
		int[] newXys = new int[xys.length];
		int newXysCounter = 0;
		for(int i = 0; i < xys.length; i+=2){
			int[] newXy = transformCoordinatesPair(new int[]{xys[i], xys[i+1]});
			newXys[newXysCounter++] = newXy[0];
			newXys[newXysCounter++] = newXy[1];
		}
		return newXys;
	}
	
}
